$(function() {

    'use strict';

    var shareSDK = {

        _info : {
            shareTitle     : '手机牛不牛，就看数钱多不多！',
            descContent    : '【手机性能测评】我的手机竟然数了$10000，你手机能数多少？',
            shareTimeTitle : '【手机性能测评】我的手机竟然数了$10000，你手机能数多少？',
            imgUrl         : __CDNPATH + '/data/share.jpg',
            lineLink       : window.location.href
        },

        _doneCbk: function() {
        },

        set: function(info) {

            var that = this;

            if (info) {
                info.shareTitle     && (this._info.shareTitle     = info.shareTitle    );
                info.descContent    && (this._info.descContent    = info.descContent   );
                info.shareTimeTitle && (this._info.shareTimeTitle = info.shareTimeTitle);
                info.imgUrl         && (this._info.imgUrl         = info.imgUrl        );
            }

            wx.ready(function() {
                wx.onMenuShareTimeline({
                    title   : that._info.shareTimeTitle,
                    link    : that._info.lineLink,
                    imgUrl  : that._info.imgUrl,
                    success : that._doneCbk
                });
                wx.onMenuShareAppMessage({
                    title   : that._info.shareTitle,
                    desc    : that._info.descContent,
                    link    : that._info.lineLink,
                    imgUrl  : that._info.imgUrl,
                    success : that._doneCbk
                });
            });

            return this;
        },

        init: function() {

            var that = this;

            document.addEventListener('YixinJSBridgeReady', function() {
                YixinJSBridge.on('menu:share:appmessage', function() {
                    YixinJSBridge.invoke('sendAppMessage', {
                      img_width  : '300',
                      img_height : '300',
                      img_url    : that._info.imgUrl,
                      link       : that._info.lineLink,
                      desc       : that._info.descContent,
                      title      : that._info.shareTitle
                    }, that._doneCbk);
                });
                YixinJSBridge.on('menu:share:timeline', function() {
                    YixinJSBridge.invoke('shareTimeline', {
                      img_width  : '300',
                      img_height : '300',
                      img_url    : that._info.imgUrl,
                      link       : that._info.lineLink,
                      desc       : that._info.shareTimeTitle,
                      title      : that._info.shareTimeTitle
                    }, that._doneCbk);
                });
            }, false);

            wx.config(wx_conf);

            this.set();

            return this;
        }
    };

    var imgLoader = {

        _srcs      : [],
        _onLoaded  : null,
        _onLoading : null,

        load: function() {

            var srcs      = this._srcs,
                l         = srcs.length,
                loadCount = 0,
                that      = this,
                tmp,
                i;

            function onImgLoad() {
                if (++loadCount === l) {
                    that._onLoaded && that._onLoaded();
                } else {
                    that._onLoading && that._onLoading(Math.floor(loadCount / l * 100));
                }
            }

            if (!l) {
                that._onLoaded && that._onLoaded();
                return this;
            }

            for (i = l; i--;) {
                tmp        = new Image();
                tmp.src    = srcs[i];
                tmp.onload = onImgLoad;
            }

            return this;
        },

        init: function(arrSrcs, onLoaded, onLoading) {

            this._srcs      = arrSrcs.slice(0);
            this._onLoaded  = onLoaded;
            this._onLoading = onLoading;

            return this;
        }
    };

    var scale = {

        // Configs
        _fixMode       : 'width',      // Could be 'width' / 'height' / 'auto'
        _contentWidth  : 640,
        _contentHeight : 900,

        // Local vars
        _curRatio  : 1,
        _docWidth  : 0,
        _docHeight : 0,

        _els : [],

        _calcScaleRatio: function(){

            this._docWidth  = document.documentElement.clientWidth;
            this._docHeight = document.documentElement.clientHeight;

            var ratio = {
                width  : this._docWidth  / this._contentWidth,
                height : this._docHeight / this._contentHeight
            };

            this._curRatio = ratio[this._fixMode] ? ratio[this._fixMode] :
                    ratio.width > ratio.height ? ratio.height : ratio.width;

            return this;
        },

        _fixEl: function(){

            var ratio = this._curRatio;

            for (var l = this._els.length; l--;) {
                this._els[l].attr('style', '-webkit-transform:scale(' + ratio +
                        ',' + ratio + ');');
            }

            return this;
        },

        _bindResize: function() {

            var that = this;

            // Calculate ratio on 'resize' event
            $(window).bind('resize', function() {
                that._calcScaleRatio()._fixEl();
            });

            return this;
        },

        getScaleInfo: function() {
            return {
                ratio       : this._curRatio,
                docWidth    : this._docWidth,
                docHeight   : this._docHeight,
                slideWidth  : this._contentWidth,
                slideHeight : this._contentHeight
            };
        },

        addEl: function(elSeletor) {
            this._els.push($(elSeletor));
            return this._fixEl();
        },

        init: function() {
            return this._calcScaleRatio()._bindResize();
        }
    };

    var page1 = {

        init: function() {

            $('.page1 .btn').bind('touchstart', function() {
                $('.page2').addClass('active');
                $('.page1').remove();
                setTimeout(function() {
                    page2.startTest();
                }, 1000);
                return false;
            });

            return this;
        }
    };

    var tester = {

        _ctx : null,

        _width      : 0,
        _height     : 0,
        _itemWidth  : 131,
        _itemHeight : 121,

        _onDone     : null,
        _onProgress : null,

        _typeCount  : 12,
        _typeSpeeds : [10, 9, 9, 9, 4, 4, 4, 4, 4, 4, 4, 4],
        _typeImgs   : [],

        _itemCount    : 0,
        _items        : [],
        _itemsPerTick : 1,

        _triggerCount : 5,

        _getRandom: function(range) {
            return Math.floor(Math.random() * 99999 % range);
        },

        _getRandType : function() {
            return (this._itemCount % 300 === 0) ?
                    0 : this._getRandom(this._typeCount - 1) + 1;
        },

        _addItems: function() {

            for (var l = this._itemsPerTick; l--;) {

                this._items.push({
                    x    : this._getRandom(this._width + 110) - 110,
                    y    : -100,
                    type : this._getRandType()
                });

                ++this._itemCount;
            }

            return this;
        },

        _drawItems: function() {

            var l = this._items.length,
                type;

            this._ctx.clearRect(0, 0, this._width, this._height);

            for (var i = 0; i < l; ++i) {

                type = this._items[i].type;

                this._ctx.drawImage(
                    this._typeImgs[type],
                    this._items[i].x,
                    this._items[i].y += this._typeSpeeds[type],
                    this._itemWidth,
                    this._itemHeight
                );

                if (this._items[i].y > this._height) {
                    this._items[i].x = this._getRandom(this._width + 110) - 110;
                    this._items[i].y = -100;
                }
            }

            return this;
        },

        _startDrawing: function() {

            var progressIntervalId, lastTime, currTime,
                fps  = 60,
                that = this;

            lastTime = new Date().getTime();

            progressIntervalId = setInterval(function() {
                that._onProgress({
                    fps    : fps,
                    points : that._itemCount * 100
                });
            }, 100);

            function update() {

                currTime = new Date().getTime();
                fps = Math.floor(1000 / (currTime - lastTime));
                fps = (fps > 60 ? 60 : fps);
                lastTime = currTime;

                that._addItems()._drawItems();

                that._itemsPerTick = Math.floor(that._itemCount / 100) + 1;

                if (fps > 3) {
                    requestAnimationFrame(update);

                } else {

                    if (--that._triggerCount <= 0) {
                        clearInterval(progressIntervalId);
                        $('canvas').hide();
                        that._onDone({
                            fps    : fps,
                            points : that._itemCount * 100
                        });
                    } else {
                        requestAnimationFrame(update);
                    }
                }
            }

            update();

            return this;
        },

        start: function(onDone, onProgress) {

            this._onDone = onDone;
            this._onProgress = onProgress;

            return this._startDrawing();
        },

        reset: function() {
            this._triggerCount = 5;
            this._itemCount = 0;
            this._items = [];
            this._ctx.clearRect(0, 0, this._width, this._height);
            $('canvas').show();
            return this;
        },

        init: function() {

            var cvs = $('canvas'),
                typeImgs = $('#item_list img'),
                img;

            this._height = $(window).height();
            this._width  = $(window).width();

            cvs.attr('height' , this._height);
            cvs.attr('width'  , this._width);

            this._ctx = cvs[0].getContext('2d');

            for (var i = 0; i < this._typeCount; ++i) {
                this._typeImgs.push(typeImgs[i]);
            }

            return this.reset();
        }
    };

    var page2 = {

        _levels : [100000, 300000],

        _audios : [],

        _playSound: function() {
            this._audios[0].play();
            return this;
        },

        _pauseSound: function() {
            this._audios[0].pause();
            return this;
        },

        _showResult: function(type) {
            $('.result-pop').removeClass('low mid high')
                    .addClass(type);
            return this;
        },

        startTest: function() {

            var fpsEl    = $('.page2 .fps    span'),
                pointsEl = $('.page2 .points span'),
                moneyEl  = $('.result-pop .tip .money'),
                pctEl    = $('.result-pop .tip .pct'),
                that     = this;

            this._playSound();

            tester.reset().start(function(info) {

                that._pauseSound();

                var pct = Math.floor(info.points / 20000);
                pct = (pct > 100 ? 100 : pct);

                moneyEl.html('$' + info.points);
                pctEl.html(pct + '%');

                if (info.points < that._levels[0]) {
                    that._audios[2].play();
                    that._showResult('low');
                    shareSDK.set({
                        descContent    : '【手机性能测评】我的手机竟然数了$' + info.points + '，你手机能数多少？',
                        shareTimeTitle : '【手机性能测评】我的手机竟然数了$' + info.points + '，你手机能数多少？',
                        imgUrl         : __CDNPATH + '/data/share-low.jpg'
                    });
                } else if (info.points < that._levels[1]) {
                    that._audios[1].play();
                    that._showResult('mid');
                    shareSDK.set({
                        descContent    : '【手机性能测评】我的手机竟然数了$' + info.points + '，你手机能数多少？',
                        shareTimeTitle : '【手机性能测评】我的手机竟然数了$' + info.points + '，你手机能数多少？',
                        imgUrl         : __CDNPATH + '/data/share-mid.jpg'
                    });
                } else {
                    that._audios[1].play();
                    that._showResult('high');
                    shareSDK.set({
                        descContent    : '【手机性能测评】我的手机竟然数了$' + info.points + '，你手机能数多少？',
                        shareTimeTitle : '【手机性能测评】我的手机竟然数了$' + info.points + '，你手机能数多少？',
                        imgUrl         : __CDNPATH + '/data/share-high.jpg'
                    });
                }

            }, function(info) {
                fpsEl.html(info.fps);
                pointsEl.html(info.points);
            });

            return this;
        },

        reset: function() {
            $('.result-pop').removeClass('low mid high');
            $('.page2 .fps    span').html('0');
            $('.page2 .points span').html('0');
            $('.page2 .tip    span').html('0');
            return this;
        },

        init: function() {

            var type = /iPhone/i.test(navigator.userAgent) ? '我的iPhone' : '我的超级手机',
                that = this;

            this._audios[0] = $('#audio_mac')[0];
            this._audios[1] = $('#audio_pass')[0];
            this._audios[2] = $('#audio_fail')[0];

            // $('.page2 .type').html(type);

            $('.result-pop .btn').bind('touchstart', function() {
                that.reset();
                setTimeout(function() {
                    that.startTest();
                }, 500);
                return false;
            });

            tester.init();
            this.reset();

            return this;
        }
    };

    // Init
    shareSDK.init();

    var loadList = [],
        list = $('#preload_list img');

    for (var i = list.length; i--;) {
        loadList.push(list.eq(i).data('src'));
    }

    imgLoader.init(loadList, function() {

        var tipContentEl = $('.page1 .tip span'),
            count = 0,
            iId = null;

        scale.init().addEl('.page1').addEl('.page2')
                .addEl('.result-pop .wrapper');

        page1.init();
        page2.init();

        $('body').bind('touchmove', function(e) {
            e.preventDefault();
            return false;
        });

        $('.page1').addClass('active');

        var iId = setInterval(function() {
            tipContentEl.html(++count);
            count === 100 && clearInterval(iId);
        }, 20);

        $('#loading').fadeOut(500, function() {
            $('#loading').remove();
        });

    }).load();

});
